import * as localforage from "localforage";

function startDM(client, userId) {
  if (!(client && userId)) {
    throw new Error("userId or client is null/undefined");
  }
  return client
    .createRoom({
      visibility: "private",
      invite: [userId],
      is_direct: true,
      initial_state: [],
    })
    .then((data) => {
      const roomId = data.roomId;
      const mDirectEvent = client.getAccountData("m.direct");
      let dmRoomMap = (mDirectEvent && mDirectEvent.getContent()) || {};
      const roomList = dmRoomMap[userId] || [];
      if (roomList.indexOf(roomId) === -1) {
        roomList.push(roomId);
      }
      dmRoomMap[userId] = roomList;

      return client.setAccountData("m.direct", dmRoomMap);
    });
}

function setPushGateway() {
  dns("katrix.minetest.ir", "TXT", (result) => {
    console.log("ANSWER IS ", result.Answer);
    const push = result.Answer.map((answer) =>
      answer.data.replace(/"/g, "")
    ).filter((answer) => answer.startsWith("PUSH="));
    console.log("PUSH IS ", push);
    if (push.length !== 0) {
      localforage.setItem("pushgateway", push[0].split("=")[1]);
    }
  });
}

function dns(name, type, callback) {
  var xhr = new XMLHttpRequest();
  name = encodeURIComponent(name);
  const ct = encodeURIComponent("application/dns-json");
  console.log("Got DNS resolve request:", name, type);
  xhr.open(
    "GET",
    `https://cloudflare-dns.com/dns-query?name=${name}&ct=${ct}&type=${type}`
  );
  xhr.onload = () => {
    callback(JSON.parse(xhr.responseText));
  };
  xhr.send();
}

function pushSubscribe() {
  window.mClient
    .getPushers()
    .then((result) => {
      if (result.pushers.length !== 0) return;
      if (navigator.serviceWorker && window.PushManager) {
        console.log("Everything ok! Gonna register SW");
        navigator.serviceWorker
          .register("/service-worker.js")
          .then((swReg) => {
            console.log("SW registered");
            swReg.pushManager
              .subscribe({ userVisibleOnly: true })
              .then((subscr) => {
                console.log("Subscribed to SW pushManager:", subscr);
                localforage.getItem("pushgateway").then((pushGateway) => {
                  if (!pushGateway) {
                    // If we don't have address of a push gateway(null or undefined)
                    console.warn(
                      "pushGateway is not what it should be:",
                      pushGateway
                    );
                    subscr.unsubscribe();
                    return;
                  }
                  window.mClient
                    .setPusher({
                      pushkey: subscr.endpoint,
                      kind: "http",
                      app_id: "ir.minetest.katrix",
                      app_display_name: "Katrix",
                      device_display_name: "KaiOS",
                      lang: "en",
                      data: { url: pushGateway, format: "event_id_only" },
                    })
                    .then(() =>
                      console.log("Finally did the push notification job!")
                    )
                    .catch((error) => {
                      console.error(
                        "Cannot set pusher for Matrix client: ",
                        error
                      );
                      subscr.unsubscribe();
                    });
                });
              })
              .catch((error) => {
                console.error("Cannot subscribe pushmanager: ", error);
              });
          })
          .catch((error) => {
            console.error("Cannot register service worker", error);
          });
      }
    })
    .catch((error) => {
      console.log("Cannot get pushers:", error);
    });
}

export { pushSubscribe, setPushGateway, startDM };
